package proto

import (
	"crypto/cipher"

	"golang.org/x/crypto/blowfish"
)

type Encryptor struct {
	IV     []byte
	Key    []byte
	Mode   string
	Cipher string
}

// Encrypt encrypt plainData with blowfish algorithm in CBC mode.
// key的长度应当大于0 ，小于57.
func Encrypt(plainData []byte, key, iv string) ([]byte, error) {
	keyB := []byte(key)
	ivB := []byte(iv)
	var blockCipher cipher.Block
	var cipherMode cipher.BlockMode
	var err error
	blockCipher, err = blowfish.NewCipher(keyB)
	if err != nil {
		return nil, err
	}
	cipherMode = cipher.NewCBCEncrypter(blockCipher, ivB)
	textLen := len(plainData)
	modLen := blockCipher.BlockSize() - (textLen % blockCipher.BlockSize())
	plainData = append(plainData, make([]byte, modLen)...)
	encryptedText := make([]byte, textLen+modLen)
	cipherMode.CryptBlocks(encryptedText, plainData)
	return encryptedText, nil
}

func Decrypt(encryptedData []byte, key, iv string) ([]byte, error) {
	keyB := []byte(key)
	ivB := []byte(iv)
	var blockCipher cipher.Block
	var cipherMode cipher.BlockMode
	var err error
	blockCipher, err = blowfish.NewCipher(keyB)
	if err != nil {
		return nil, err
	}
	cipherMode = cipher.NewCBCDecrypter(blockCipher, ivB)
	plainData := make([]byte, len(encryptedData))
	cipherMode.CryptBlocks(plainData, encryptedData)
	dataLen := len(plainData)
	for dataLen > 0 {
		if plainData[dataLen-1] != 0 {
			break
		}
		dataLen -= 1
	}
	return plainData[:dataLen], nil
}
